{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Python 机器学习实战 ——代码样例\n",
    "\n",
    "# 第九章 Python 程序性能分析初步"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 9.5 用装饰器记录执行时间\n",
    "\n",
    "首先用一个比较简单的、也是比较通用的装饰器方法，通过调用被装饰的函数，然后分别记录下执行这个函数前后的时间，相减即可以得到程序执行时间"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Total time running random_sort: 0.40099167823791504seconds\n"
     ]
    }
   ],
   "source": [
    "import time\n",
    "from functools import wraps\n",
    "import random\n",
    " \n",
    "def func_timer(function):\n",
    "    @wraps(function)\n",
    "    def function_timer(*args, **kwargs):\n",
    "        t0 = time.time()\n",
    "        result = function(*args, **kwargs)\n",
    "        t1 = time.time()\n",
    "        print('Total time running {fname}: {fsec}seconds'.format(fname=function.__name__, \n",
    "              fsec=str(t1-t0)))\n",
    "        return result\n",
    "    return function_timer\n",
    "\n",
    "@func_timer\n",
    "def random_sort():\n",
    "    n = 100000\n",
    "    sorted([random.randrange(n) for i in range(n)])\n",
    "\n",
    "random_sort()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 loop, best of 3: 201 ms per loop\n",
      "1 loop, best of 10: 234 ms per loop\n"
     ]
    }
   ],
   "source": [
    "# 使用%timeit 来记录执行时间：\n",
    "\n",
    "import random\n",
    "\n",
    "def random_sort():\n",
    "    n = 100000\n",
    "    sorted([random.randrange(n) for i in range(n)])\n",
    "\n",
    "%timeit random_sort()\n",
    "%timeit -r10 random_sort()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 9.7.\t分析每一行代码的执行时间\n",
    "\n",
    "我们可以使用 line_profiler 模块来分析每一行代码的执行时间：\n",
    "（需要首先pip安装 line_profiler库，windows用户可以在此下载：\n",
    "https://www.lfd.uci.edu/~gohlke/pythonlibs/#line_profiler ）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "import random\n",
    "\n",
    "def random_sort():\n",
    "    n = 100000\n",
    "    sorted([random.randrange(n) for i in range(n)])\n",
    "    \n",
    "%load_ext line_profiler\n",
    "%lprun -f random_sort random_sort()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 输出结果如下： \n",
    "'''\n",
    "Timer unit: 3.64673e-07 s\n",
    "\n",
    "Total time: 0.499204 s\n",
    "File: <ipython-input-6-adc78929df8e>\n",
    "Function: random_sort at line 3\n",
    "\n",
    "Line #      Hits         Time  Per Hit   % Time  Line Contents\n",
    "==============================================================\n",
    "     3                                           def random_sort():\n",
    "     4         1          7.0      7.0      0.0      n = 100000\n",
    "     5         1    1368902.0 1368902.0    100.0      sorted([random.randrange(n) for i in range(n)])\n",
    "'''"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 9.10.\tCPU等性能测试\n",
    "\n",
    "获得 CPU 的核心数以及真实的核心数，可以简单的执行下面的脚本"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "4\n",
      "2\n"
     ]
    }
   ],
   "source": [
    "import psutil\n",
    "\n",
    "print(psutil.cpu_count())\n",
    "print(psutil.cpu_count(logical=False))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[scputimes(user=110737.6875, system=116889.25, idle=1051485.625, interrupt=4627.25, dpc=2522.828125),\n",
       " scputimes(user=132982.140625, system=110993.375, idle=1035136.625, interrupt=454.734375, dpc=79.78125),\n",
       " scputimes(user=160333.953125, system=142513.75, idle=976264.5, interrupt=477.171875, dpc=58.234375),\n",
       " scputimes(user=211106.21875, system=167102.75, idle=900903.25, interrupt=351.390625, dpc=49.265625)]"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 显示 CPU的所有逻辑信息：\n",
    "\n",
    "psutil.cpu_times(percpu=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "33.9"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 获得 CPU使用百分比：\n",
    "\n",
    "psutil.cpu_percent()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "svmem(total=16827559936, available=10226556928, percent=39.2, used=6601003008, free=10226556928)\n"
     ]
    }
   ],
   "source": [
    "# 获得内存占用情况：\n",
    "\n",
    "mem = psutil.virtual_memory()\n",
    "print(mem)\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
